package com.runa.rccprotocol.analysis.huizhong;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.runa.monitor.comm.dto.newComm.HotMeterVO;
import com.runa.monitor.comm.dto.newComm.ValveVO;
import com.runa.persistence.DateUtil;
import com.runa.protocol.enums.ByteOrder;
import com.runa.protocol.util.ByteUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 2024/10/9 13:04
 * zhangYB
 */
@Data
@Slf4j
public class HuiZhongOneResponse {

    private int l;

    private byte c;

    private String netSerial;

    private byte afn;
    private byte seq;
    private byte fn;

    private byte totalFrames;
    private byte currentFrame;
    private byte meterNum;

    private Date readTime;

    private int index;

    private byte meterType;

    private String serial;

    private byte valid;

    private Date meterDate;

    private HotMeterVO meterVO;
    private ValveVO valveVO;

    private String message;


    public void handleData(byte[] data, int index) {
        try {
            index++;
            this.setL(ByteUtil.byteToShort(data, index, ByteOrder.AB) >> 2 & 0xff);
            index += 5;
            this.setC(data[index++]);
            this.setNetSerial(ByteUtil.byteToHexStringFlip(data, index, 5));
            index += 5;
            this.setAfn(data[index++]);
            this.setSeq(data[index++]);
            this.setFn(data[index++]);

            this.setTotalFrames(data[index++]);
            this.setCurrentFrame(data[index++]);
            this.setMeterNum(data[index++]);

            this.readTime = new SimpleDateFormat("yyMMddHHmmss").parse(ByteUtil.byteToHexStringFlip(data, index, 6));
            index += 6;

            this.setIndex(ByteUtil.byteToUShort(data, index, ByteOrder.BA));
            index += 2;

            this.setMeterType(data[index++]);

            this.setSerial(ByteUtil.byteToHexStringFlip(data, index, 7).replaceAll("F", ""));
            index += 7;

            this.setValid(data[index++]);

            if (this.valid == 0x26) {
                index = this.handleMeterData(data, index);
                this.handleValveData(data, index);
            } else {
                meterVO = new HotMeterVO();
                meterVO.setMeterSerial(serial);
                meterVO.setSuccess(false);
                valveVO = new ValveVO();
                valveVO.setSuccess(false);
            }

            log.debug("response: {}", JSON.toJSONString(this));
        } catch (Exception e) {
            log.error("", e);
        }
    }



    private int handleMeterData(byte[] data, int index) {
        HotMeterVO meterVO = new HotMeterVO();
        meterVO.setMeterSerial(serial);
        meterVO.setReadDate(readTime);
        this.setMeterVO(meterVO);
        //累积热量
        double theCurrentHeatSum = ByteUtil.bcdToInt(data, index, 4, false) * 0.01;
        meterVO.setAccHeat((float) theCurrentHeatSum);
        index += 4;
        ++index;
        //瞬时流量
        double instantaneousDelivery = ByteUtil.bcdToInt(data, index, 4, false) * 0.0001;
        meterVO.setFlow((float) instantaneousDelivery);
        index += 4;
        ++index;
        //累计流量
        double cumulativeDischarge = ByteUtil.bcdToInt(data, index, 4, false) * 0.01;
        meterVO.setAccFlow((float) cumulativeDischarge);
        index += 5;
        //进水温
        double intoTheWater = ByteUtil.bcdToInt(data, index, 3, false) * 0.01;
        meterVO.setSupplyTemp((float) intoTheWater);
        index += 3;
        //回水温度
        double returnWaterTemperature = ByteUtil.bcdToInt(data, index, 3, false) * 0.01;
        meterVO.setReturnTemp((float) returnWaterTemperature);
        index += 3;
        //热功率
//        ++index;
        double thermalPower = ByteUtil.bcdToInt(data, index, 4, false) * 0.01;
        meterVO.setPower((float) thermalPower);
        index += 4;
        ++index;
        //无单位,累计工作时间
        int openTime = ByteUtil.bcdToInt(data, index, 4, false);
        meterVO.setWorkTime(openTime);
        index += 4;

        // 状态
        byte status = data[index++];
        if (status != 0) {
            meterVO.setFaultCode(meterFaultCodeList(status));
        }
        meterVO.setStatus(ByteUtil.byteToHexString(status));

        this.meterDate = DateUtil.stringToDate(ByteUtil.bcd2str(data, index, 6, false), "yyMMddHHmmss");
        meterVO.setMeterDate(this.meterDate);
        index += 6;

        return index;
    }

    private List<String> meterFaultCodeList(byte status) {
        List<String> faultCodeList = new ArrayList<>();
        byte l = (byte)(status & 0x0F);
        switch (l) {
            case 5:
                faultCodeList.add("传感器和换能器之间通讯故障，无通讯");
                break;
            case 6:
                faultCodeList.add("E2PROM 损坏");
        }
        if ((status & 1) == 1) {
            faultCodeList.add("电池电压低于3.37V，需要更换电池");
        }
        if ((status >> 1 & 1) == 1) {
            faultCodeList.add("空管或者换能器故障无测量信号");
        }
        if ((status >> 2 & 1) == 1) {
            faultCodeList.add("电池电压低于3.3V，必须更换电池");
        }
        if ((status >> 4 & 1) == 1) {
            faultCodeList.add("供水温度传感器故障（短路、开路）或供水温度低于2");
        }
        if ((status >> 5 & 1) == 1) {
            faultCodeList.add("供水温度超出150");
        }
        if ((status >> 6 & 1) == 1) {
            faultCodeList.add("回水温度传感器故障（短路、开路）或回水温度低于2");
        }
        if ((status >> 7 & 1) == 1) {
            faultCodeList.add("回水温度超出150");
        }

        return faultCodeList;
    }

    private void handleValveData(byte[] data, int index) {
        this.valveVO = new ValveVO();
        valveVO.setReadTime(readTime);
        valveVO.setValveDate(meterDate);
        byte status = data[index++];
        valveVO.setStatus(ByteUtil.byteToHexString(status));

        int openStatus = status & 0x03;
        if (openStatus == 0) {
            // 开
            valveVO.setActOpen(100f);
        } else if (openStatus == 1) {
            // 关
            valveVO.setActOpen(0f);
        } else if (openStatus == 2) {
            // 无
            List<String> faultCodeList = new ArrayList<>();
            faultCodeList.add("无");
            valveVO.setFaultCode(faultCodeList);
        } else if (openStatus == 3) {
            // 异常
            valveVO.setFaultCode(valveFaultCodeList(status));
        }

        if ((status >> 7 & 1) == 1) {
            // 调节阀
            valveVO.setActOpen((float)data[index++]);
        }
    }


    private List<String> valveFaultCodeList(byte status) {
        List<String> faultCodeList = new ArrayList<>();
        if ((status >> 2 & 1) == 1) {
            faultCodeList.add("室温控制器电池电压欠压");
        }
        return faultCodeList;
    }

    public boolean inValid() {
        return !(valid == 0x26);
    }
}
